#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <assert.h>

#include "defs.h"
#include "tools.h"

#define IPPACKMSIZ 65536

static char buffer[IPPACKMSIZ];
static struct Msg msg;

void * read_tun(void * arg)
{
    printf("Start read_tun ...\n");
    int len;
    msg.type = 103;
    int data_siz = sizeof(msg.data);
    while (1)
    {
        if ((len = read(tun, buffer, IPPACKMSIZ)) > 0)
        {
            uint16_t plen = ntohs(*(uint16_t *)(buffer + 2));
            p_time_prompt("TUN");
            printf(">>>>> %u(%u) bytes >>>>>\n", plen, len);
            struct in_addr *pv4addr = (struct in_addr *)(buffer + 16);
            uinfoptr le = utable_he;
            for (; le != NULL; le = le->pNext)
                if (v4addr_eql(&le->v4addr, pv4addr))
                    break;
            if (NULL != le)
            {
                for (char *he = buffer; he - buffer < len;)
                {
                    uint32_t msg_len;
                    if (data_siz < len - (he - buffer))
                        msg_len = data_siz;
                    else
                        msg_len = len - (he - buffer);
                    memcpy(&msg.data, he, msg_len);
                    he += msg_len;
                    msg_len += 5; // Msg head
                    msg.length = htonl(msg_len);
                    write_all(le->fd, &msg, msg_len);
                    p_time_prompt("SEND");
                    printf("<<<<< %u bytes <<<<<\n", msg_len);
                    p_buf(&msg, 25, msg_len);
                }
            }
        }
    }
}
